package com.tbit.uqbike.webmanager.controller;

import cn.hutool.core.util.StrUtil;
import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.common.enums.OperaPswEnum;
import com.tbit.uqbike.annos.OperateLog;
import com.tbit.uqbike.constant.MapConstant;
import com.tbit.uqbike.constant.UserConstant;
import com.tbit.uqbike.enums.SystemCodeEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.Geo;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.uqbike.service.base.CalibrateService;
import com.tbit.uqbike.service.base.GeoService;
import com.tbit.uqbike.service.business.OperaPswService;
import com.tbit.uqbike.webmanager.util.excel.ExcelUtil;
import com.tbit.utils.Assert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.util.List;


/**
 * @author chenmengran
 * @Description: 运营区域
 * @date 2019\12\11 001115:28
 */
@Slf4j
@Validated
@RestController
@RequestMapping(value = "/geo", produces = BaseController.MEDIA_JSON_UTF8)
public class GeoController extends BaseController {

    @Autowired
    private CalibrateService calibrateService;
    @Autowired
    private GeoService geoService;
    @Autowired
    private OperaPswService operaPswService;

    //添加运营区域
    @RequestMapping("/add")
    @OperateLog(module = ModuleEnum.GEO, methods = MethodEnum.GEO_ADD)
    public JsonResult add(Geo geo, @NotNull(message = "ver.mapType.notNull") Integer mapType, HttpServletRequest request) {
        /* 校验 */
        Assert.hasLength(geo.getName(), "ver.name.notNull");
        Assert.hasLength(geo.getPoints(), "ver.points.notNull");
        Assert.notNull(geo.getGeoType(), "ver.geoType.notNull");
        Assert.notNull(geo.getGeoSwitch(), "ver.geoSwitch.notNull");
        Assert.notNull(geo.getCutSwitch(), "ver.cutSwitch.notNull");
        Assert.notNull(geo.getRecoverSwitch(), " ver.recoverSwitch.notNull");
        Assert.notNull(geo.getCutTimeLong(), "ver.cutTimeLong.notNull");
        if (geo.getName().length() > 100){
            throw new BaseException("服务区名称过长");
        }else if (StrUtil.isNotEmpty(geo.getRemark()) && geo.getRemark().length() > 255){
            throw new BaseException("服务区备注过长");
        }

        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }

        LoginInfo loginInfo = getLogin(request);
        if (loginInfo == null) {
            throw new BaseException(SystemCodeEnum.LOGIN_EXPIRED);
        }
        if (loginInfo.type.equals(UserConstant.USER_AGENT)) {
            geo.setAccountId(loginInfo.id);
        }

        Assert.notNull(geo.getAccountId(), "ver.accountId.notNull");
        //经纬度校验s
        calibrateService.calGeo(geo, mapType, MapConstant.MAP_ORI);
        geoService.insert(geo, loginInfo);
        return JsonResult.ok(null);
    }

    //修改运营区域
    @RequestMapping("/edit")
    @OperateLog(module = ModuleEnum.GEO, methods = MethodEnum.GEO_EDIT)
    public JsonResult edit(Geo geo, Integer geoId, @NotNull(message = "ver.mapType.notNull") Integer mapType, HttpServletRequest request) {
        /* 校验 */
        Assert.notNull(geo.getGeoId(), "ver.geoId.notNull");
        Assert.hasLength(geo.getName(), "ver.name.notNull");
        Assert.hasLength(geo.getPoints(), "ver.points.notNull");
        Assert.notNull(geo.getGeoType(), "ver.geoType.notNull");
        Assert.notNull(geo.getGeoSwitch(), "ver.geoSwitch.notNull");
        Assert.notNull(geo.getCutSwitch(), "ver.cutSwitch.notNull");
        Assert.notNull(geo.getRecoverSwitch(), " ver.recoverSwitch.notNull");
        Assert.notNull(geo.getCutTimeLong(), "ver.cutTimeLong.notNull");
        if (geo.getName().length() > 100){
            throw new BaseException("服务区名称过长");
        }else if (StrUtil.isNotEmpty(geo.getRemark()) && geo.getRemark().length() > 255){
            throw new BaseException("服务区备注过长");
        }
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }

        LoginInfo loginInfo = getLogin(request);
        if (loginInfo == null) {
            throw new BaseException(SystemCodeEnum.LOGIN_EXPIRED);
        }
        //经纬度校验
        calibrateService.calGeo(geo, mapType, MapConstant.MAP_ORI);
        geoService.edit(geo, loginInfo);

        return JsonResult.ok(null);
    }

    //删除运营区域
    @RequestMapping("/del")
    @OperateLog(module = ModuleEnum.GEO, methods = MethodEnum.GEO_DEL)
    public JsonResult del(@NotNull(message = "ver.geoId.notNull") Integer geoId, String operaPsw, HttpServletRequest request) {
        /* 校验 */
        LoginInfo loginInfo = getLogin(request);
        if (loginInfo == null) {
            throw new BaseException(SystemCodeEnum.LOGIN_EXPIRED);
        }

        /**操作密码校验*/
        operaPswService.checkOperaPsw(loginInfo, OperaPswEnum.OPERA_PSW_SYSTEM_CONFIG.getModule(), operaPsw);

        //经纬度校验s
        geoService.del(geoId, loginInfo);

        return JsonResult.ok(null);
    }

    //获取运营区域
    @RequestMapping("/getByAccount")
    public JsonResult getByAccount(@NotNull(message = "ver.accountId.notNull") Integer accountId, Integer mapType, HttpServletRequest request) {
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }
        /* 校验 */
        LoginInfo loginInfo = getLogin(request);
        if (loginInfo == null) {
            throw new BaseException(SystemCodeEnum.LOGIN_EXPIRED);
        }
        List<Geo> geoList = geoService.getByAccountId(accountId, loginInfo);
        return JsonResult.ok(geoList);
    }

    /**
     * 获取导出信息
     * @param accountId 区域id
     * @param mapType   地图类型
     * @param request   request请求
     * @return  excel结果
     */
    @GetMapping("/exportGeo")
    @OperateLog(module = ModuleEnum.GEO, methods = MethodEnum.GEO_EDIT)
    public JsonResult exportGeo(@NotNull(message = "ver.accountId.notNull") Integer accountId, Integer mapType, HttpServletRequest request){
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }
        /* 校验 */
        if (permissionCheck(request)){
            List<Geo> geoList = geoService.getExportByAccountId(accountId);
            if (!geoList.isEmpty()){
                ExcelUtil<Geo> excelUtil = new ExcelUtil<>(Geo.class);
                JsonResult jsonResult = excelUtil.exportExcel(geoList,String.format("服务区坐标集-服务区名称%s",geoList.get(0).getName()));
                String fileName = jsonResult.getData().toString();
//                try {
//                    String outFileMd5 = DigestUtils.md5Hex(new FileInputStream(excelUtil.getAbsoluteFile(fileName)));
//                    // 缓存文件的md5 一天 ，防止文件被篡改
//                    redisService.add(outFileMd5,"",7, TimeUnit.DAYS);
//                } catch (IOException e) {
//                    log.error("获取文件的MD5错误",e);
//                }
                return JsonResult.ok(fileName);
            }
        }
        return JsonResult.ok();
    }

    /**
     * 导入服务区
     */
    @PostMapping("/importGeo")
    @OperateLog(module = ModuleEnum.GEO, methods = MethodEnum.GEO_EDIT)
    public JsonResult importGeo(@NotNull(message = "ver.accountId.notNull") Integer accountId, @RequestParam("file") MultipartFile file, Integer mapType, HttpServletRequest request){
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }
//        try {
//            ExcelUtil<Geo> excelUtil = new ExcelUtil<>(Geo.class);
//            String inFileMd5 = DigestUtils.md5Hex(file.getInputStream());
//            if (redisService.get(inFileMd5) == null){
//                throw new BaseException("文件已被篡改或过期，禁止导入");
//            }
//        } catch (IOException e) {
//            log.error("获取文件的MD5错误",e);
//        }
        if (permissionCheck(request)){
            geoService.importGeo(file,accountId,mapType);
        }
        return JsonResult.ok();
    }

    /**
     * 服务区导入导出限制
     * @param request 请求
     * @return 返回
     */
    private boolean permissionCheck(HttpServletRequest request){
        /* 校验 */
        LoginInfo loginInfo = getLogin(request);
        if (loginInfo == null) {
            throw new BaseException(SystemCodeEnum.LOGIN_EXPIRED);
        }
        if (!UserConstant.USER_ADMIN.equals(loginInfo.getType())) {
            throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
        }
        return true;
    }

}
